package com.qcxy.gzy.activity.v1;

import android.os.Bundle;

import com.google.gson.Gson;
import com.qcxy.gzy.activity.base.BaseSwitchActivity;
import com.qcxy.gzy.bean.ComReceiveDataBean;
import com.qcxy.gzy.bean.SerialPortCommand;
import com.qxcy.gzy.util.PreferencesUtils;
import com.qxcy.gzy.util.SerialPortUtils;

import java.util.Timer;
import java.util.TimerTask;

/*
 * 此Activity主要用于切换电机
 * */
public abstract class SwitchEMActivity extends BaseSwitchActivity {
    //当前流程状态
    // (-2-标识停止电机命令已发送状态；-1-标识读电机停止是否成功状态；
    // 0-标识旧制动器关闭命令已发送；1-标识旧制动器读状态为关闭成功；
    // 2-标识新制动器打开命令已发送；3-标识新制动器读状态为打开成功；
    // 4-标识启动电机命令已发送状态；5-标识读电机启动是否成功命令状态；
    // 6-标识命令发送结束
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        initTimer();
        builder = new StringBuilder();
        builder.append("------------------------------------------------------------------------\n");
    }

    //切换到大电机
    protected void switchToEMBig() {
        switchEM(SerialPortUtils.ElectricMachineryBig);
    }

    //切换到小电机
    protected void switchToEMSmall() {
        switchEM(SerialPortUtils.ElectricMachinerySmall);
    }

    private void switchEM(@SerialPortUtils.ElectricMachineryType int emType) {
        showLoadingView();
        builder.append("希望切换电机:").append(emType == SerialPortUtils.ElectricMachineryBig ? "大电机" : "小电机").append("\n");
        if (isEMRunning) {
            //电机正在运行
            if (runEMType != emType) {
                status = -2;
                //发送电机停止运行命令
                byte[] commandEMStop = SerialPortUtils.getEMCommand(runEMType, SerialPortUtils.EMActionStop);
                currentCommand = new SerialPortCommand(commandEMStop, SerialPortCommand.COM_TYPE_EM_STOP);
                sendCommand(currentCommand);
            }
        } else {
            runEMType = emType;
            status = 2;
            //电机未运行，发送制动器打开命令
            byte[] commandBrake = SerialPortUtils.getBradeCommandFromEM(runEMType, SerialPortUtils.BrakeActionOpen);
            currentCommand = new SerialPortCommand(commandBrake, SerialPortCommand.COM_TYPE_BRAKE_OPEN);
            sendCommand(currentCommand, SerialPortUtils.SerialPortSwitch);
        }
    }

    //发送单条命令
    protected void sendCommand(SerialPortCommand command) {
        sendCommand(command, SerialPortUtils.SerialPortDefault);
    }

    /**
     * @param command   命令
     * @param delayTime 单位为10ms
     */
    protected void sendCommand(SerialPortCommand command, int delayTime) {
        if (resendThread != null) {
            resendThread.stopSend();
            resendThread = null;
        }
        resendThread = new autoResendThread(command, delayTime);
        new Thread(resendThread).start();
    }

    @Override
    protected void onDataReceived(ComReceiveDataBean ComRecData) {
        builder.append("收到返回值：").append(new Gson().toJson(ComRecData.bRec)).append("\n");
        w("收到:" + json(ComRecData.bRec));
        if (ComRecData.getCRC(ComRecData.bRec).equals("0")) {
            isCommandRun = false;
            if (resendThread != null) {
                resendThread.stopSend();
                resendThread = null;
            }
            //根据读写动作区分操作
            byte type = ComRecData.bRec[1];
            switch (type) {
                case SerialPortUtils.typeRead:
                    //读取寄存器数据
                    byte x = ComRecData.bRec[4];
                    switch (status) {
                        case -1: {
                            w("电机寄存器:" + x);
                            if (x == 0x07) {
                                //结束10s计时器
                                stopTimer();
                                if (isImp()) {
                                    ((SwitchEMListener) this).onSwitch(false, "电机故障，请重启", runEMType);
                                }
                                return;
                            }
                            //电机停止状态
                            if (x == 0x05 || x == 0x00) {
                                builder.append("停止电机成功，当前停止的电机为：").append(runEMType == SerialPortUtils.ElectricMachineryBig ? "大电机" : "小电机").append("\n");
                                isEMRunning = false;
                                PreferencesUtils.put(SwitchEMActivity.this, SerialPortUtils.EM_STATUS, false);
                                status = 0;
                                //结束10s计时器
                                stopTimer();
                                //电机未运行，发送旧制动器关闭命令
                                byte[] commandBrake = SerialPortUtils.getBradeCommandFromEM(runEMType, SerialPortUtils.BrakeActionClose);
                                currentCommand = new SerialPortCommand(commandBrake, runEMType + "---" + SerialPortCommand.COM_TYPE_BRAKE_CLOSE);
                                sendCommand(currentCommand, SerialPortUtils.SerialPortSwitch);
                            } else {
                                if (timeOutNum < readWaitTime) {
                                    //读电机寄存器状态命令
                                    byte[] commandEMStatus = SerialPortUtils.getReadCommand(runEMType, SerialPortUtils.ReadEM);
                                    currentCommand = new SerialPortCommand(commandEMStatus, SerialPortCommand.COM_TYPE_EM_READ);
                                    sendCommand(currentCommand);
                                }
                            }
                        }
                        break;
                        case 1: {
                            //当前读取的是制动器寄存器
                            if (x == 0x00) {
                                builder.append("关闭制动器成功，当前关闭的制动器为").append(runEMType == SerialPortUtils.ElectricMachineryBig ? "控制器2" : "控制器1").append("\n");
                                //设置制动器成功
                                status = 2;
                                //结束10s计时器
                                stopTimer();
                                //旧电机已关闭，关联制动器已关闭，设置期望开启电机类型
                                runEMType = runEMType == SerialPortUtils.ElectricMachineryBig ? SerialPortUtils.ElectricMachinerySmall : SerialPortUtils.ElectricMachineryBig;
                                //发送制动器打开运行命令
                                byte[] commandBrakeStart = SerialPortUtils.getBradeCommandFromEM(runEMType, SerialPortUtils.BrakeActionOpen);
                                currentCommand = new SerialPortCommand(commandBrakeStart, runEMType + "---" + SerialPortCommand.COM_TYPE_BRAKE_OPEN);
                                sendCommand(currentCommand, SerialPortUtils.SerialPortSwitch);
                            } else {
                                if (timeOutNum < readWaitTime) {
                                    //获取需要读取的制动器类型
                                    int BrakeType = runEMType == SerialPortUtils.ElectricMachineryBig ? SerialPortUtils.ReadBrakeBig : SerialPortUtils.ReadBrakeSmall;
                                    //发送读控制器寄存器命令
                                    byte[] commandBrakeStatus = SerialPortUtils.getReadCommand(runEMType, BrakeType);
                                    currentCommand = new SerialPortCommand(commandBrakeStatus, SerialPortCommand.COM_TYPE_BRAKE_READ);
                                    sendCommand(currentCommand);
                                }
                            }
                        }
                        break;
                        case 3: {
                            //当前读取的是制动器寄存器
                            if (x == 0x01) {
                                builder.append("打开制动器成功，当前制动器为").append(runEMType == SerialPortUtils.ElectricMachineryBig ? "控制器2" : "控制器1").append("\n");
                                //设置制动器成功
                                status = 4;
                                //结束10s计时器
                                stopTimer();
                                //发送电机启动运行命令
                                byte[] commandEMStart = SerialPortUtils.getEMCommand(runEMType, SerialPortUtils.EMActionStart);
                                currentCommand = new SerialPortCommand(commandEMStart, SerialPortCommand.COM_TYPE_EM_START);
                                sendCommand(currentCommand);
                            } else {
                                if (timeOutNum < readWaitTime) {
                                    //获取需要读取的制动器类型
                                    int BrakeType = runEMType == SerialPortUtils.ElectricMachineryBig ? SerialPortUtils.ReadBrakeBig : SerialPortUtils.ReadBrakeSmall;
                                    //发送读控制器寄存器命令
                                    byte[] commandBrakeStatus = SerialPortUtils.getReadCommand(runEMType, BrakeType);
                                    currentCommand = new SerialPortCommand(commandBrakeStatus, SerialPortCommand.COM_TYPE_BRAKE_READ);
                                    sendCommand(currentCommand);
                                }
                            }
                        }
                        break;
                        case 5: {
                            w("电机寄存器:" + x);
                            if (x == 0x07) {
                                //结束10s计时器
                                stopTimer();
                                if (isImp()) {
                                    ((SwitchEMListener) this).onSwitch(false, "电机故障，请重启", runEMType);
                                }
                                return;
                            }
                            //电机运行状态
                            if (x == 0x04) {
                                builder.append("启动电机成功，当前启动的电机为：").append(runEMType == SerialPortUtils.ElectricMachineryBig ? "大电机" : "小电机").append("\n");
                                isEMRunning = true;
                                PreferencesUtils.put(SwitchEMActivity.this, SerialPortUtils.EM_STATUS, true);
                                status = 6;
                                //结束10s计时器
                                stopTimer();
                                if (isImp()) {
                                    ((SwitchEMListener) SwitchEMActivity.this).onSwitch(true, "切换成功", runEMType);
                                }
                            } else {
                                if (timeOutNum < readWaitTime) {
                                    //读电机寄存器状态命令
                                    byte[] commandEMStatus = SerialPortUtils.getReadCommand(runEMType, SerialPortUtils.ReadEM);
                                    currentCommand = new SerialPortCommand(commandEMStatus, SerialPortCommand.COM_TYPE_EM_READ);
                                    sendCommand(currentCommand);
                                }
                            }
                        }
                        break;
                    }
                    break;
                case SerialPortUtils.typeWrite:
                    //根据地址区分命令
                    byte address = ComRecData.bRec[3];
                    status++;
                    //开启10s计时器
                    timeOutNum = 0;
                    startTimer();
                    if (address == SerialPortUtils.addressEMControl) {
                        //读电机寄存器状态命令
                        byte[] commandEMStatus = SerialPortUtils.getReadCommand(runEMType, SerialPortUtils.ReadEM);
                        currentCommand = new SerialPortCommand(commandEMStatus, SerialPortCommand.COM_TYPE_EM_READ);
                        sendCommand(currentCommand);
                    } else {
                        //制动器1或者2
                        int BradeType = address == SerialPortUtils.brakeStatusBig ? SerialPortUtils.ReadBrakeBig : SerialPortUtils.ReadBrakeSmall;
                        //发送读控制器寄存器命令
                        byte[] commandBrakeStatus = SerialPortUtils.getReadCommand(runEMType, BradeType);
                        currentCommand = new SerialPortCommand(commandBrakeStatus, SerialPortCommand.COM_TYPE_BRAKE_READ);
                        sendCommand(currentCommand);
                    }
                    break;
            }

            //解析返回值
            //******************************************************************************************
            //如果返回的数据为电机停止命令发送结果
            //--------------------------------操作成功
            // 检查status=-2，则->status=-1,10s读电机停止是否成功结果
            //******************************************************************************************
            //如果返回的数据为读电机状态结果
            //--------------------------------操作成功
            //status=-1且电机为停止状态，则->isEMRunning=false，status=0,发送切换电机命令；否则->status=-1,10s重复读
            //status=5且电机为启动状态，则->isEMRunning=true;status=6,提醒用户切换成功；否则->status=5,10s重复读
            //******************************************************************************************
            //如果返回的数据为制动器关闭命令发送结果
            //--------------------------------操作成功
            //检查status=0，则->status=1,10s读制动器关闭是否成功结果
            //******************************************************************************************
            //如果返回的数据为读制动器状态结果
            //--------------------------------操作成功
            //检查status=1，且关闭成功，则->status=2，发送指定制动器打开命令；
            // 检查status=3，且打开成功，则->status=4，发送期望电机启动命令；
            // 否则->status=1,10s重复读
            //******************************************************************************************
            //如果返回的数据为制动器打开命令发送结果
            //--------------------------------操作成功
            //检查status=2，则->status=3,10s读制动器打开是否成功结果
            //******************************************************************************************
            //如果返回的数据为电机启动命令发送结果
            //--------------------------------操作成功
            // 检查status=4，则->status=5,10s读电机启动是否成功结果
        } else {
            builder.append("校验失败\n");
        }
    }

    //10秒切换超时计时器相关**************************************************************************
    //计时器（10s读）
    private Timer timer;
    private TimerTask task;
    private int timeOutNum = 0;

    private void initTimer() {
        timer = new Timer();
        task = new TimeOutTask();
    }

    //启动计时器
    private void startTimer() {
        /*
         * java.util.Timer.schedule(TimerTask task, long delay, long period)：
         * 这个方法是说，delay/1000秒后执行task,然后进过period/1000秒再次执行task，
         * 这个用于循环任务，执行无数次，当然，你可以用timer.cancel();取消计时器的执行。
         */
        initTimer();
        try {
            timer.schedule(task, 1000, 1000);
        } catch (IllegalStateException e) {
            e.printStackTrace();
            initTimer();
            timer.schedule(task, 1000, 1000);
        }
    }

    private void autoStopTimer() {
        if (timer != null) {
            timer.cancel();
        }
    }

    private void stopTimer() {
        if (timer != null) {
            timer.cancel();
        }
        //置零
        timeOutNum = 0;
    }

    private void destroyTimer() {
        timer = null;
        task = null;
    }


    protected class TimeOutTask extends TimerTask {

        @Override
        public void run() {
            timeOutNum++;
            if (timeOutNum >= readWaitTime) {
                autoStopTimer();
                String message = "";
                switch (status) {
                    case -2:
                    case -1:
                        message = "停止电机失败";
                        break;
                    case 0:
                    case 1:
                        message = "切换制动器失败";
                        break;
                    case 2:
                    case 3:
                        message = "启动电机失败";
                        break;
                }
                //提示用户10s切换失败
                if (isImp()) {
                    ((SwitchEMListener) SwitchEMActivity.this).onSwitch(false, message, runEMType);
                }
            }
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        //当activity不在前台是停止定时
        stopTimer();
    }

    @Override
    public void onDestroy() {
        //销毁时停止定时
        stopTimer();
        destroyTimer();
        super.onDestroy();
    }
}